XMLHttpRequest provides the ability to listen to various events that can occur while the request is being processed. This includes periodic progress notifications, error notifications, and so forth.
Support for DOM progress event monitoring of XMLHttpRequest transfers follows the specification for progress events: these events implement the ProgressEvent interface. The actual events you can monitor to determine the state of an ongoing transfer are:
progressThe amount of data that has been retrieved has changed.
loadThe transfer is complete; all data is now in the response
jsconst req = new XMLHttpRequest();req.addEventListener("progress", updateProgress);req.addEventListener("load", transferComplete);req.addEventListener("error", transferFailed);req.addEventListener("abort", transferCanceled);req.open();// …// progress on transfers from the server to the client (downloads)function updateProgress(event) { if (event.lengthComputable) {const percentComplete = (event.loaded / event.total) * 100;// … } else {// Unable to compute progress information since the total size is unknown }}function transferComplete(evt) { console.log("The transfer is complete.");}function transferFailed(evt) { console.log("An error occurred while transferring the file.");}function transferCanceled(evt) { console.log("The transfer has been canceled by the user.");}We add event listeners for the various events that are sent while performing a data transfer using XMLHttpRequest.
Note: You need to add the event listeners before calling open() on the request. Otherwise the progress events will not fire.
The progress event handler, specified by the updateProgress() function in this example, receives the total number of bytes to transfer as well as the number of bytes transferred so far in the event's total and loaded fields. However, if the lengthComputable field is false, the total length is not known and will be zero.
Progress events exist for both download and upload transfers. The download events are fired on the XMLHttpRequest object itself, as shown in the above sample. The upload events are fired on the XMLHttpRequest.upload object, as shown below:
jsconst req = new XMLHttpRequest();req.upload.addEventListener("progress", updateProgress);req.upload.addEventListener("load", transferComplete);req.upload.addEventListener("error", transferFailed);req.upload.addEventListener("abort", transferCanceled);req.open();Note: Progress events are not available for thefile: protocol.
Progress events come in for every chunk of data received, including the last chunk in cases in which the last packet is received and the connection closed before the progress event is fired. In this case, the progress event is automatically fired when the load event occurs for that packet. This lets you now reliably monitor progress by only watching the "progress" event.
One can also detect all three load-ending conditions (abort,load, or error) using the loadend event:
jsreq.addEventListener("loadend", loadEnd);function loadEnd(e) { console.log("The transfer finished (although we don't know if it succeeded or not).", );}Note there is no way to be certain, from the information received by the loadend event, as to which condition caused the operation to terminate; however, you can use this to handle tasks that need to be performed in all end-of-transfer scenarios.